/*
PearReview - The peer review assistant.
Copyright (C) 2009  Dimitrij Pankratz, Anton Musichin
http://www.pearreview.com, info@pearreview.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package com.pearreview.ui.list;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.io.Serializable;
import java.net.URI;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

import com.pearreview.ui.ImageLoader;

public class ImageListCellRenderer extends JComponent 
		implements ListCellRenderer, Serializable {
	
	private static final long serialVersionUID = 3108567263302312028L;
	
	public static final int IMAGE_WIDTH = 110;
	public static final int IMAGE_HEIGHT = 110;
	
	private Icon image;
	
	private String loadingText = "loading";
	
	private Map<URI, Icon> thumbs = 
			new LinkedHashMap<URI, Icon>();
	
	public ImageListCellRenderer() {
		setLayout(null);
		
		Dimension dim = new Dimension(IMAGE_WIDTH + 6, IMAGE_HEIGHT + 6);
		setPreferredSize(dim);
		setMaximumSize(dim);
		setMinimumSize(dim);
	}
	
	@Override
	public Component getListCellRendererComponent(JList list, Object value,
			int index, boolean isSelected, boolean cellHasFocus) {
		
		if(!(value instanceof URI)) {
			DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
			dlcr.getListCellRendererComponent(list, 
					value, 
					index, 
					isSelected, 
					cellHasFocus);
			
			return dlcr;
		}
		
		URI element = (URI) value;
		
		if (thumbs.containsKey(element)) {
			setIcon(thumbs.get(element));
		} else {
			setIcon(null);
			ListImageLoader loader = new ListImageLoader(list, 
					element, 
					IMAGE_WIDTH, 
					IMAGE_HEIGHT);
			loader.execute();
		}
		
		if(isSelected) {
			setForeground(list.getSelectionForeground());
			setBackground(list.getSelectionBackground());
		} else {
			setForeground(list.getForeground());
			setBackground(list.getBackground());
		}
		
		return this;
	}
	
	public Icon getIcon() {
		return image;
	}
	
	public void setIcon(Icon icon) {
		image = icon;
	}
	
	public void setLoadingText(String loadingText) {
		this.loadingText = loadingText;
	}
	
	public String getLoadingText() {
		return loadingText;
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		g.setColor(getBackground());
		g.fillRect(0, 0, getWidth(), getHeight());
		
		if (getIcon() != null) {
			int x = getWidth()/2 - getIcon().getIconWidth()/2;
			int y = getHeight()/2 - getIcon().getIconHeight()/2;

			if (y < 0) {
				y = 0;
			}

			if (x < 0) {
				x = 0;
			}
			getIcon().paintIcon(this, g, x, y);
		} else {
			g.setColor(getForeground());
			g.drawString(getLoadingText(), 5, getHeight()/2);
		}
	}
	
	private class ListImageLoader extends ImageLoader {
		private static final long serialVersionUID = 704894725363275268L;
		private Component list;
		public ListImageLoader(Component comp, URI uri, int width, int height) {
			super(uri, width, height);
			this.list = comp;
			thumbs.put(getLoadPath(), null);
		}
		@Override
		public void error(Throwable e, Icon icon) {
			e.printStackTrace();
			putIcon(icon);
		}
		@Override
		public void success(Icon icon) {
			putIcon(icon);
		}
		public void putIcon(Icon icon) {
			thumbs.put(getLoadPath(), icon);
			list.repaint();
		}
	}
}
